added SSCLI 1.0
[windows-sources.git] / shared source / sscli20 / tools / nmake / table.h
blobf237e1b18abb26e3a56358bf3f7695870e96ceb1
1 // ==++==
2 //
3 //
4 // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
5 //
6 // The use and distribution terms for this software are contained in the file
7 // named license.txt, which can be found in the root of this distribution.
8 // By using this software in any fashion, you are agreeing to be bound by the
9 // terms of this license.
10 //
11 // You must not remove this notice, or any other, from this software.
12 //
14 // ==--==
15 // TABLE.H -- contains tables used by lexer and parser
17 // Purpose:
18 // This include file contains parser tables and lexer tables.
20 // ALL VALUES USED IN THESE TABLES ARE DEFINED IN GRAMMAR.H
21 // WHEN PRODUCTIONS CHANGE, UPDATE THE FOLLOWING TABLE
23 // The first element in a production line is the number of symbols on
24 // the right-hand-side of the production arrow. If the first element
25 // is 0, the nonterminal to the left of the arrow goes to the null string.
26 // Table entries beginning w/ "DO" are actions to be carried out at
27 // that particular point in the production. All other entries are
28 // either tokens or non-terminals.
30 const UCHAR prod0[] = {0}; // MAKEFILE -> prod0 | prod1 | prod2
31 const UCHAR prod1[] = {2,
32 BLANKLINES,
33 MAKEFILE};
34 const UCHAR prod2[] = {5,
35 NEWLINE,
36 NAME,
37 DONAME,
38 BODY,
39 MAKEFILE};
40 const UCHAR prod3[] = {5, // BODY -> prod3 | prod4
41 NAMELIST,
42 SEPARATOR,
43 DOLASTNAME,
44 BUILDINFO,
45 DOBUILDCMDS};
46 const UCHAR prod4[] = {3,
47 EQUALS,
48 VALUE,
49 DOMACRO};
50 const UCHAR prod5[] = {0}; // NAMELIST -> prod5 | prod6
51 const UCHAR prod6[] = {3,
52 NAME,
53 DONAMELIST,
54 NAMELIST};
55 const UCHAR prod7[] = {0}; // COMMANDS -> prod7 | prod8 | prod9
56 const UCHAR prod8[] = {1,
57 MOREBUILDLINES};
58 const UCHAR prod9[] = {4,
59 SEMICOLON,
60 STRING,
61 DONAMELIST,
62 MOREBUILDLINES};
63 const UCHAR prod10[] = {4, // MOREBUILDLINES -> prod10 | prod 11
64 NEWLINESPACE, // | prod12
65 STRING,
66 DONAMELIST,
67 MOREBUILDLINES};
68 const UCHAR prod11[] = {0};
69 const UCHAR prod12[] = {2,
70 NEWLINE,
71 MOREBUILDLINES};
73 const UCHAR prod13[] = {0}; // BLANKLINES -> prod13 | prod14 |
74 const UCHAR prod14[] = {2, // | prod15
75 NEWLINE,
76 BLANKLINES};
77 const UCHAR prod15[] = {2,
78 NEWLINESPACE,
79 BLANKLINES};
80 const UCHAR prod16[] = {1,
81 DODEPENDS}; // BUILDINFO -> prod16 | prod17
82 const UCHAR prod17[] = {3,
83 NAMELIST,
84 DODEPENDS,
85 COMMANDS};
86 const UCHAR prod18[] = {1, COLON}; // SEPARATOR -> prod18 | prod19
87 const UCHAR prod19[] = {1, DOUBLECOLON};
89 const UCHAR * const productions[] = {
90 prod0,
91 prod1,
92 prod2,
93 prod3,
94 prod4,
95 prod5,
96 prod6,
97 prod7,
98 prod8,
99 prod9,
100 prod10,
101 prod11,
102 prod12,
103 prod13,
104 prod14,
105 prod15,
106 prod16,
107 prod17,
108 prod18,
109 prod19
113 // When either of the high bit (AMBIG_MASK) of something that isn't an ERROR
114 // condition is set, it means that there are two productions that apply for
115 // that entry, the one given, and the one given plus one. The next token
116 // token must be examined to know which production to use.
119 // name newline newline semi colon double equals $
120 // white colon colon
121 // space
122 static const UCHAR table[8][8] = {
123 {SEPRTR,1 |AMBIG_MASK, 1, SYNTAX, NOTARG, NOTARG, MACRO, 0},
124 {SYNTAX,13|AMBIG_MASK, 15, SYNTAX, SYNTAX, SYNTAX, SYNTAX, 13},
125 {PARSER,11|AMBIG_MASK, 10, PARSER, SYNTAX, SYNTAX, SYNTAX, 11},
126 {PARSER,7, 8, 9, SYNTAX, SYNTAX, SYNTAX, 7},
127 {3, SEPEQU, SEPEQU, SEPRTR, 3, 3, 4, SEPEQU},
128 {6, 5, 5, 5, 5, 5, NAMES, 5},
129 {17, 16, 17, 17, SYNTAX, SYNTAX, SYNTAX, 16},
130 {PARSER,SEPRTR, SEPRTR, SEPRTR, 18, 19, SYNTAX, SEPRTR}};
133 static const UCHAR useAlternate[3][8] = {
134 {YES, NO, NO, YES, YES, YES, YES, NO},
135 {NO, YES, YES, NO, NO, NO, NO, YES},
136 {NO, YES, YES, NO, NO, NO, NO, NO}};
138 void makeName(void);
139 void addItemToList(void);
140 void makeMacro(void);
141 void assignDependents(void);
142 void endNameList(void);
143 void assignBuildCommands(void);
145 static PFV const actions[] = {
146 makeName,
147 addItemToList,
148 makeMacro,
149 assignDependents,
150 endNameList,
151 assignBuildCommands};
154 // state tables for lexer's name and string recognizers
155 // values are defined in grammar.h
157 // d
158 // e
159 // f m
160 // a a c B
161 // u | | | | | | | | | |c h| | @ | F |
162 // l | # | = | \ | : |WS |NL | $ | ( | ) |r a| * | < | D |
163 // t | | | | | |EOF| | | |o r| | ? | R |
165 extern const UCHAR stringStates[13][14] = {
166 { 1, 2, 1, 3, 1, 2, OK, 4, 1, 1, 1, 1, 1, 1}, // 0 in col 0
167 { 1, 1, 1, 3, 1, 2, OK, 4, 1, 1, 1, 1, 1, 1}, // 1 default
168 { 1, 1, 1, 3, 1, 2, OK, 4, 1, 1, 1, 1, 1, 1}, // 2 whitespace
169 { 1, 1, 1, 1, 1, 2, 0, 4, 1, 1, 1, 1, 1, 1}, // 3 line cont.
170 {CHR,CHR,CHR,CHR,CHR,BAD,BAD,1, 5, CHR,1, 1, 1, 1}, // 4 macro inv.
171 {CHR,CHR,CHR,CHR,CHR,NAM,PAR,CHR,CHR,NAM,6, 11, 8, 6}, // 5 found (
172 {CHR,CHR,CHR,CHR,9, PAR,PAR,CHR,CHR,2, 6, BAD,BAD,6}, // 6 legal name
173 {CHR,CHR,CHR,CHR,9, PAR,PAR,CHR,CHR,2, BAD,BAD,BAD,BAD}, // 7 ext sp mac
174 {CHR,CHR,CHR,CHR,9, PAR,PAR,CHR,CHR,2, BAD,BAD,BAD,7}, // 8 sp ch aft(
175 {10, 10, SEQ,10, 10, 10, PAR,10, 10, SEQ,10, 10, 10, 10}, // 9 found a :
176 {10, 10, 12, 10, 10, 10, PAR,10, 10, EQU,10, 10, 10, 10}, //10 macro subs
177 {CHR,CHR,CHR,CHR,9, PAR,PAR,CHR,CHR,2, BAD, 8, BAD,7}, //11 found $(*
178 {12, 12, 12, 12, 12, 12, PAR,12, 12, 2, 12, 12, 12, 12}}; //12 look for )
181 // In the above table, the columns hold the next state to go to
182 // for the given input symbol and the lines represent the states
183 // themselves.
185 // WS stands for whitespace, meaning space or tab
186 // NL stands for newline, EOF stands for end of file
187 // macrochar is any alphanumeric character or underscore
188 // * is used in the special macros $* and $** ($** is the only
189 // two-letter macro that doesn't require parentheses, thus
190 // we must treat it specially)
191 // @ < ? are characters found in special macros (they are not
192 // allowed in the names of a user-defined macros)
193 // BFDR are modifiers to special macros which may be appended
194 // to the macro name (but they necessitate the use of
195 // parentheses in the macro invocation)
196 // # is the comment char. # is a comment anywhere on a macro
197 // definition line, but is only a comment if it appears in
198 // column 0 of a build line. If we're lexing the tools
199 // initialization file, then semicolon is also a comment char
200 // if it appears in column 0. (Note that the only way
201 // to have a pound sign appear in the makefile and NOT be
202 // considered a comment is to define a macro "$A = #" on
203 // the commandline that invokes nmake.)
204 // default is anything not contained in the above groups and not
205 // appearing above a column in the table
207 // OK means that we accept the string
208 // all other mnemonic values are error codes (see end of grammar.h)
211 // the states: there is no state to handle comments -- if we see a
212 // comment char and we're not ignoring comments, we eat
213 // the comment and get another input symbol before consulting
214 // the state table
216 // 0 initial state -- for all practical purposes, we can
217 // assume that we're in column 0. If we're getting a
218 // macro value, we don't care what column we're in.
219 // If we're getting a build line, the only way we won't
220 // be in column 0 is if we're getting a command following
221 // a semicolon on the target-dependency line. If the
222 // use puts a comment char here, I think it's reasonable
223 // to treat it as a comment, since it comes at the beginning
224 // of the build command, even though the command itself
225 // doesn't start in column 0.
226 // We return to the initial state after seeing space-
227 // backslash-newline.
229 // 1 on any input symbol that isn't a backslash, comment char,
230 // or whitespace, we move here whenever we're not in a
231 // comment, or a macro definition
233 // 2 if the input symbol is whitespace, we move here whenever
234 // we're not in a comment or a macro definition.
236 // 3 We move here from states 0, 1, or 2 when we've seen a
237 // backslash, because if it's followed by a newline, we
238 // continue getting the string from the next line of the file.
239 // If the next character is a backslash, followed by a newline,
240 // there's a kludge in lexer.c that ignores the second back-
241 // slash.
242 // (The above applies to v. 1.5. v. 1.0 requires whitespace
243 // before a backslash.)
245 // 4 we move here when we see a dollar sign -- this is where
246 // all the error checking starts. We make sure that the
247 // macro name is legal, that the substitution sequences
248 // are specified correctly (if any is specified at all),
249 // and that parens match up. If our next input is $, a
250 // special-macro char, or a legal char in a user-defined-
251 // macro name, we go back to state 1.
253 // 5 found an open paren
255 // 6 found a legal macrochar
257 // 7 go here for an extended special macro, and from here we
258 // look for a close paren (out of order w/ 8)
260 // 8 we found a special-macro char after the open paren
261 // If we find a special-macro modifier
262 // after the special macro char following the open paren
263 // then we go to 7
265 // 9 found a colon (meaning that the user is going to do
266 // some substitution in the macro value)
268 // 10 any character that isn't newline, right paren, or EOF
269 // brings us here,a nd we loop until we see an equals sign.
270 // Newline, EOF, or right paren generate error messages.
272 // 11 we move here from state 5 if we see an asterisk, because
273 // we have to check for a second asterisk. A second *
274 // takes us to state 8 (because a modifier may follow **).
275 // If we find a modifier here (instead of a 2nd *), we go
276 // to state 7.
278 // 12 found an equals sign, so we loop, picking up characters
279 // for the replacement string, until we find a close paren.
280 // Newline, EOF generate error messages.
284 // The following table is used to recognize names
285 // It differs from the previous one in that we don't have to deal
286 // w/ continuations or comments, and we don't allow special macros
287 // (other than the dynamic dependency macros) to be used as part
288 // of names.
290 // d
291 // e
292 // f m
293 // a a c
294 // u | | | | | | | | | |c h| | | |
295 // l | # | = | ; | : |WS |NL | $ | ( | ) |r a| { | } | \ | "
296 // t | | | | | |EOF| | | |o r| | | |
298 extern const UCHAR nameStates[19][15] = {
299 {1, OK, OK, OK, 1, OK, OK, 2, 1, 1, 1, 8, 1, BKS,16}, // 0 initial state
300 {1, OK, OK, OK, OK, OK, OK, 2, 1, 1, 1, 8, 1, BKS,QUO},// 1 do normal name
301 {CHR,BAD,CHR,CHR,CHR,BAD,BAD,1, 3, CHR,1, CHR,CHR,CHR,CHR},// 2 handle macro
302 {CHR,PAR,CHR,CHR,NAM,NAM,PAR,CHR,CHR,NAM,4, CHR,CHR,CHR,CHR},// 3 do macro name
303 {CHR,PAR,CHR,CHR,5, PAR,PAR,CHR,CHR,1, 4, CHR,CHR,CHR,CHR},// 4 do mac (name)
304 {6, 6, SEQ,6, 6, 6, PAR,6, 6, EQU,6, 6, 6, 6 ,6}, // 5 found : do sub
305 {6, 6, 7, 6, 6, 6, SEQ,6, 6, SEQ,6, 6, 6, 6 ,6}, // 6 read until =
306 {7, 7, 7, 7, 7, 7, SEQ,7, 7, 1, 7, 7, 7, 7 ,7}, // 7 read until )
307 {8, OK, 8, 8, 8, 8, OK, 9, 8, 8, 8, 8, 18, 8 ,8}, // 8 do path list
308 {CHR,BAD,CHR,CHR,CHR,BAD,BAD,8, 10, CHR,8, CHR,CHR,CHR,CHR},// 9 do macro in {}
309 {CHR,PAR,CHR,CHR,NAM,10, PAR,CHR,CHR,NAM,11, CHR,CHR,CHR,CHR},//10 do macro name
310 {CHR,PAR,CHR,CHR,12, PAR,PAR,CHR,CHR,8, 11, CHR,CHR,CHR,CHR},//11 do mac (name)
311 {13, 13, SEQ,13, 13, 13, PAR,13, 13, EQU,13, 13, 13, 13 ,13}, //12 found : do sub
312 {13, 13, 14, 13, 13, 13, SEQ,13, 13, SEQ,13, 13, 13, 13 ,13}, //13 read until =
313 {14, 14, 14, 14, 14, 14, SEQ,14, 14, 8, 14, 14, 14, 14 ,14}, //14 read until )
314 {1, OK, OK, OK, OK, OK, OK, 2, 1, 1, 1, 8, 1, 1 ,1}, //15 \ found so ...
315 {16, 16, 16, 16, 16, 16, NOQ,2, 16, 16, 16, 8, 16, BKS,17}, //16 quoted name
316 {OK, OK, OK, OK, OK, OK, OK, OK, OK, OK, OK, OK, OK, OK ,OK}, //17 quoted name
317 {1, OK, OK, OK, OK, OK, OK, 2, 1, 1, 1, 8, 1, BKS,16}};//18 read after {}
320 // this is to allow macros inside path portions of rules, e.g.
321 // {$(abc)}.c{$(def)}.obj: .......
322 // or foo : {$a;$(bcd);efg\hijk\}lmn.opq .......
324 // We now enter state 18 as soon as a path list is read. (We used
325 // to return to state 1 in that case and generate an error as
326 // soon as the quotes were encountered)
327 // Also changed state[8][5] from OK to 8 in order to allow paths
328 // containing white space.